// vim: set filetype=c :
//
// Delegates.generated.cs:
//
// Authors:
//   Rolf Bjarne Kvinge <rolf@xamarin.com>
//
// Copyright 2013-2014 Xamarin Inc.
//

/*
 * This file was generated from Delegates.cs.t4, any modifications will be lost once this file is re-generated.
 */

<#@ include file="delegates.t4" #>
#if !COREBUILD
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;

using Foundation;
using Registrar;

namespace ObjCRuntime {
	public unsafe partial class Runtime {
		
<# foreach (var d in delegates) { #>
		internal delegate <#= d.MReturnType #> <#= d.SimpleEntryPoint #>_delegate (<#= d.MArgumentSignature #>);
<# } #>

		internal struct Delegates {
<# foreach (var d in delegates) { #>
			public IntPtr <#= d.SimpleEntryPoint #>;
<# } #>
		}

<# 		foreach (var d in delegates) { #>
		[MonoPInvokeCallback (typeof (<#= d.SimpleEntryPoint #>_delegate))]
		static <#= d.MReturnType #> <#= d.SimpleEntryPoint #> (<#= d.MArgumentSignature #>)
<# if (d.ExceptionHandling) { #>
		{	
			exception_gchandle = 0;
			try {
<# if (string.IsNullOrEmpty (d.WrappedManagedFunction)) { #>
				throw new NotImplementedException ();
<# } else { #>
				<# if (d.MReturnType != "void") { #>return <# } #><#=d.WrappedManagedFunction#> (<#=d.MArgumentNames#>);
<# } #>
			} catch (Exception ex) {
				var handle = GCHandle.Alloc (ex, GCHandleType.Normal);
				exception_gchandle = GCHandle.ToIntPtr (handle).ToInt32 ();
<# if (d.SimpleEntryPoint == "get_nsobject_with_type") { #>				created = false;
<# } #>
<# if (d.MReturnType != "void") { #>				return default (<#= d.MReturnType #>);
<# } #>
			}
		}
<# } else { #>
		{	
<# if (string.IsNullOrEmpty (d.WrappedManagedFunction)) { #>
			throw new NotImplementedException ();
<# } else { #>
			<# if (d.MReturnType != "void") { #>return <# } #><#=d.WrappedManagedFunction#> (<#=d.MArgumentNames#>);
<# } #>
		}
<# } #>

<# } #>

		[BindingImpl (BindingImplOptions.Optimizable)] // To inline the Runtime.DynamicRegistrationSupported code if possible.
		static void RegisterDelegates (InitializationOptions* options)
		{
<# foreach (var d in delegates) {
	if (d.OnlyDynamicUsage) continue; #>
			options->Delegates-><#= d.SimpleEntryPoint #> = GetFunctionPointer (new <#= d.SimpleEntryPoint #>_delegate (<#= d.SimpleEntryPoint #>));
<# } #>

			// The linker will remove this condition (and the subsequent method call) if possible
			if (DynamicRegistrationSupported)
				RegisterDelegatesDynamic (options);
		}

		static void RegisterDelegatesDynamic (InitializationOptions* options)
		{
<# foreach (var d in delegates) {
	if (!d.OnlyDynamicUsage) continue; #>
			options->Delegates-><#= d.SimpleEntryPoint #> = GetFunctionPointer (new <#= d.SimpleEntryPoint #>_delegate (<#= d.SimpleEntryPoint #>));
<# } #>
		}
	}
}
#endif
